﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;

using Stp.Core.Data;

namespace Stp.Core
{
    public class Account : IAccount
    {
        private AccountModel _accountModel;
        private IRegistry _cRegistry;
        private IEmailAgent _emailAgent;
        private IAccountMapper _accountMapper;

        public Account(AccountModel accountModel)
            : this(accountModel, CoreRegistry.GetInstance(), new EmailAgent())
        {

        }

        public Account(AccountModel accountModel, IRegistry cRegistry, IEmailAgent emailAgent)
        {
            _accountModel = accountModel;
            _cRegistry = cRegistry;
            _emailAgent = emailAgent;

            DatalayerInfo dInfo = _cRegistry.GetDatalayerInfo();
            _accountMapper = PluginFactory.GetPlugin(_cRegistry.CurrentPath, dInfo.AssemblyName, dInfo.DefaultNamespace, "AccountMapper") as IAccountMapper;
        }

        public bool VerifyData()
        {
            bool cRslt = VerifyCountryName();
            bool eRslt = VerifyEmailAddressFormat();

            if (cRslt != false && eRslt != false)
                return true;
            else
                return false;
        }

        private bool VerifyEmailAddressFormat()
        {
            return Regex.IsMatch(_accountModel.Email, @"^([\w-\.]+)@((\[[0–9]{1,3}\.[0–9]{1,3}\.[0–9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0–9]{1,3})(\]?)$");
        }

        private bool VerifyCountryName()
        {
             return _cRegistry.FindCountry(_accountModel.Country);
        }

        public void Register()
        {
            if (VerifyData())
            {
                byte[] pswHash = new byte[] { };
                string tempPassword = PasswordGenerator.GetRandom(out pswHash);

                _accountModel.Password = pswHash;
                _accountModel.DateCreated = DateTime.Today.ToShortDateString();
                _accountModel.Status = "Registered";

                _accountMapper.CreateAccount(_accountModel);
                _emailAgent.SendAcRegEmail(tempPassword, _accountModel.Email);
            }
        }

        public bool Login()
        {
            if (VerifyEmailAddressFormat())
            {
                AccountModel aModel = _accountMapper.FindAccountByEmail(_accountModel.Email);
                byte[] storedHash = aModel.Password;
                byte[] enteredHash = _accountModel.Password;

                if (storedHash.Length != enteredHash.Length)
                    return false;
                else
                {
                    for (int i = 0; i < storedHash.Length; i++)
                    {
                        if (!storedHash[i].Equals(enteredHash[i]))
                            return false;
                    }
                    _accountMapper.UpdateAccountStatus(_accountModel.Email, "Online");
                    return true;
                }
            }
            else
                return false;
        }

        public void Logout()
        {
            _accountMapper.UpdateAccountStatus(_accountModel.Email, "Offline");
        }
    }
}
